package cn.yrec.rain.analysis.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.yrec.rain.analysis.mappers.HyQHourRtMapper;
import cn.yrec.rain.analysis.model.HyQHourRt;
import cn.yrec.rain.analysis.service.HyQHourRtService;
import cn.yrec.rain.analysis.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 描述:
 * 水文站业务层接口实现类
 *
 * @createDate: 2020/08/24 下午 10:55:44
 * @author: yanglichen
 */
@Service
public class HyQHourRtServiceImpl implements HyQHourRtService {

    @Autowired
    private HyQHourRtMapper hyQHourRtMapper;

    /**
     * 方法描述: 根据站码和起止时间得到这段时间内的数据
     *
     * @param stcd      站码
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 结果集
     * @author yanglichen
     * @date 2020-08-24 23:19
     **/
    @Override
    public List<HyQHourRt> findByStcdAndDate(String stcd, Date startDate, Date endDate) {
        return findHyQHourListByStcdAndDate(stcd, startDate, endDate);
    }

    /**
     * 方法描述: 得到最大洪峰实例
     *
     * @param hyQHourRtList 时段的结果集
     * @return 最大流量实例
     * @author yanglichen
     * @date 2020-08-24 23:26
     **/
    @Override
    public HyQHourRt getMaxFlowEntity(List<HyQHourRt> hyQHourRtList) {
        //构造结果
        HyQHourRt result = new HyQHourRt();
        //遍历查询的列表
        //初始化最大值流量为0
        double maxFlow = 0;
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            //判断流量是否比maxQ大
            if (hyQHourRt.getFlow() != null) {
                if (hyQHourRt.getFlow() > maxFlow) {
                    maxFlow = hyQHourRt.getFlow();
                    result.setDate(hyQHourRt.getDate());
                    result.setFlow(maxFlow);
                    result.setStnm(hyQHourRt.getStnm());
                }
            }
        }
        return result;
    }

    /**
     * 方法描述: 得到最大含沙量实例
     *
     * @param hyQHourRtList 时段的结果集
     * @return 最大含沙量实例
     * @author yanglichen
     * @date 2020-08-24 23:26
     **/
    @Override
    public HyQHourRt getMaxQsEntity(List<HyQHourRt> hyQHourRtList) {
        //构造结果
        HyQHourRt result = new HyQHourRt();
        //遍历查询的列表
        //初始化最大值流量为0
        double maxQS = 0;
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            //判断流量是否比maxQ大
            if (hyQHourRt.getQs() != null) {
                if (hyQHourRt.getQs() > maxQS) {
                    maxQS = hyQHourRt.getQs();
                    result.setDate(hyQHourRt.getDate());
                    result.setQs(maxQS);
                    result.setStnm(hyQHourRt.getStnm());
                }
            }
        }
        if(result.getQs()==null){
            return null;
        }
        return result;
    }

    /**
     * 方法描述: 得到时段的水位数据
     *
     * @param hyQHourRtList 查询的结果
     * @return 时段的水位数据
     * @author yanglichen
     * @date 2020-08-25 00:06
     **/
    @Override
    public List<Double> getDateFlow(List<HyQHourRt> hyQHourRtList) {
        //构造结果集
        List<Double> dateFlow = new ArrayList<>();
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            dateFlow.add(hyQHourRt.getFlow());
        }
        return dateFlow;
    }

    /**
     * 方法描述: 得到时段的流量数据(日)
     *
     * @param hyQHourRtList 查询的结果
     * @return 时段的流量数据(日)
     * @author yanglichen
     * @date 2020-08-25 08:48
     **/
    @Override
    public List<Double> getDateFlowByDate(List<HyQHourRt> hyQHourRtList) {
        Map<Date, Double> map = new LinkedHashMap<>();
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            Date tempDate = new Date(hyQHourRt.getDate().getTime());
            Date date = DateUtils.getNotHourDate(tempDate);
            Date nextDate = new Date(date.getTime() + DateUtils.ONE_DAY_MILLI_SECOND);
            //判断这一天的数据是否存在于这个时间范围内
            if (hyQHourRt.getDate().getTime() >= date.getTime() && hyQHourRt.getDate().getTime() <= nextDate.getTime()) {
                map.put(date, hyQHourRt.getFlow());
            }
        }
        List<Double> result = new ArrayList<>(map.values());
        return result;
    }

    /**
     * 方法描述: 得到时段的含沙量数据
     *
     * @param hyQHourRtList 查询的结果
     * @return 时段的含沙量数据
     * @author yanglichen
     * @date 2020-08-25 00:06
     **/
    @Override
    public List<Double> getDateQs(List<HyQHourRt> hyQHourRtList) {
        //构造结果集
        List<Double> dateLevel = new ArrayList<>();
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            Double qs = hyQHourRt.getQs();
            if (qs == null) {
                qs = 0D;
            }
            dateLevel.add(qs);
        }
        return dateLevel;
    }

    /**
     * 方法描述: 得到时段的含沙量数据(日)
     *
     * @param hyQHourRtList 查询的结果
     * @return 时段的含沙量数据(日)
     * @author yanglichen
     * @date 2020-08-25 08:48
     **/
    @Override
    public List<Double> getDateQsByDate(List<HyQHourRt> hyQHourRtList) {
        Map<Date, Double> map = new LinkedHashMap<>();
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            Date tempDate = new Date(hyQHourRt.getDate().getTime());
            Date date = DateUtils.getNotHourDate(tempDate);
            Date nextDate = new Date(date.getTime() + DateUtils.ONE_DAY_MILLI_SECOND);
            //判断这一天的数据是否存在于这个时间范围内
            if (hyQHourRt.getDate().getTime() > date.getTime() && hyQHourRt.getDate().getTime() < nextDate.getTime()) {
                map.put(date, hyQHourRt.getQs());
            }
        }
        List<Double> result = new ArrayList<>(map.values());
        return result;
    }

    /**
     * 方法描述: 得到时间范围
     *
     * @param hyQHourRtList 查询的结果
     * @return 时间范围
     * @author yanglichen
     * @date 2020-08-25 00:12
     **/
    @Override
    public List<String> getTimeZone(List<HyQHourRt> hyQHourRtList) {
        //构造结果集
        List<String> timeZone = new ArrayList<>();
        //遍历
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            //转换时间格式
            String times = DateUtils.transformDateToMMDDHHmm(hyQHourRt.getDate());
            timeZone.add(times);
        }
        return timeZone;
    }

    /**
     * 方法描述: 得到总水量
     *
     * @param hyQHourRtList 查询的结果
     * @return 总水量
     * @author yanglichen
     * @date 2020-08-25 00:29
     **/
    @Override
    public Double getTotalQ(List<HyQHourRt> hyQHourRtList) {
        //初始化结果
        double totalQ = 0D;
        //遍历结果
        for (int i = 0; i < hyQHourRtList.size() - 1; i++) {
            //得到第一个元素的时间的毫秒数
            long firTime = hyQHourRtList.get(i).getDate().getTime();
            //得到第二个元素的时间的毫秒数
            long secTime = hyQHourRtList.get(i + 1).getDate().getTime();
            //得到间隔的秒数
            long tempSecond = (secTime - firTime) / 1000;
            //(上底+下底)*高/2 --> (起始流量+结束流量)*时间/2
            double q = (hyQHourRtList.get(i).getFlow() + hyQHourRtList.get(i + 1).getFlow()) * tempSecond / 2;
            totalQ += q;
        }
        //返回的时候设置单位为 亿m³
        return totalQ / 100000000;
    }

    /**
     * 方法描述: 得到总含沙量
     *
     * @param hyQHourRtList 查询的结果
     * @return 总含沙量
     * @author yanglichen
     * @date 2020-08-25 00:29
     **/
    @Override
    public Double getTotalQs(List<HyQHourRt> hyQHourRtList) {
        //初始化结果
        double totalQs = 0D;
        //遍历结果
        for (int i = 0; i < hyQHourRtList.size() - 1; i++) {
            //得到第一个元素的时间的毫秒数
            long firTime = hyQHourRtList.get(i).getDate().getTime();
            //得到第二个元素的时间的毫秒数
            long secTime = hyQHourRtList.get(i + 1).getDate().getTime();
            //得到间隔的秒数
            long tempSecond = (secTime - firTime) / 1000;
            double qs = 0;
            double fir = 0D;
            double sec = 0D;
            if (hyQHourRtList.get(i).getQs() != null) {
                fir = hyQHourRtList.get(i).getQs();
            }
            if (hyQHourRtList.get(i + 1).getQs() != null) {
                sec = hyQHourRtList.get(i + 1).getQs();
            }
            qs = (fir + sec) * tempSecond / 2;
            totalQs += qs;
        }
        //返回的时候设置单位为 吨
        return totalQs / 1000;
    }

    /**
     * 方法描述: 得到时段流量数据
     *
     * @param hyQHourRtList 查询的结果
     * @return 时段流量数据格式: [{"value":["2020-8-1 8:00", "23.123"], {"value":["2020-8-2 8:00", "43.123"], ]
     * @author yanglichen
     * @date 2020-08-28 08:48
     **/
    @Override
    public Map<String, Object> getTimeFlow(List<HyQHourRt> hyQHourRtList) {
        //遍历数据库查询的结果
        Map<String, Object> map = new HashMap<>();
        List<String[]> timeList = new ArrayList<>();
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            if (hyQHourRt.getFlow() != null) {
                String stnm = hyQHourRt.getStnm();
                //构造Map中的String[]
                String[] timeAndFlow = new String[]{DateUtil.format(hyQHourRt.getDate(), DatePattern.NORM_DATETIME_PATTERN), hyQHourRt.getFlow() + ""};
                timeList.add(timeAndFlow);
                map.put("name", stnm);
            }
        }
        map.put("value", timeList);
        return map;
    }

    /**
     * 方法描述: 得到时段流量数据
     *
     * @param hyQHourRtList 查询的结果
     * @return 时段流量数据格式: [{"value":["2020-8-1 8:00", "23.123"], {"value":["2020-8-2 8:00", "43.123"], ]
     * @author yanglichen
     * @date 2020-08-28 08:48
     **/
    @Override
    public Map<String, Object> getTimeQs(List<HyQHourRt> hyQHourRtList) {
        //遍历数据库查询的结果
        Map<String, Object> map = new HashMap<>();
        List<String[]> timeList = new ArrayList<>();
        for (HyQHourRt hyQHourRt : hyQHourRtList) {
            String stnm = hyQHourRt.getStnm();
            if (hyQHourRt.getQs() != null) {
                //构造Map中的String[]
                String[] timeAndQs = new String[]{DateUtil.format(hyQHourRt.getDate(), DatePattern.NORM_DATETIME_PATTERN), hyQHourRt.getQs() + ""};
                timeList.add(timeAndQs);
                map.put("name", stnm);
            }
        }
        map.put("value", timeList);
        return map;
    }



    /**
     * 方法描述: 根据起止时间和站码找到这段时间中的数据
     *
     * @param stcd      站码
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return
     * @author yanglichen
     * @date 2020-08-24 23:24
     **/
    private List<HyQHourRt> findHyQHourListByStcdAndDate(String stcd, Date startDate, Date endDate) {
        return hyQHourRtMapper.findByDateAndStcd(stcd, startDate, endDate);
    }

}
